package com.example.demo.service.impl;

import com.example.demo.mapper.*;
import com.example.demo.service.StoreAdminService;
import com.example.demo.utils.ApiResponse;
import com.example.demo.utils.JwtUtil;
import com.example.demo.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Date;
import java.time.Duration;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.List;

import static com.example.demo.service.impl.ReservationServiceImpl.getCurrentDate;


@Service

public class StoreAdminServiceImpl implements StoreAdminService {

    @Autowired
    private CarMapper carMapper;
    @Autowired
    private StoreAdminMapper storeAdminMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private ReservationMapper reservationMapper;
    @Autowired
    private ActualOrderMapper actualOrderMapper;
    @Autowired
    private CarModelMapper carModelMapper;
    @Transactional
    @Override
    public ApiResponse storeAdminLogin(String storeAdminID, String storeAdminPassword) {
        try {
            StoreAdmin storeAdmin = storeAdminMapper.findStoreAdminByStoreAdminIDAndStoreAdminPassword(
                    storeAdminID, storeAdminPassword);
            if (storeAdmin != null) {
                String res = JwtUtil.sign("门店管理员", storeAdminID, "StoreAdmin");
                System.out.println(res);
                //System.out.println(new ApiResponse(200, "门店管理员登陆成功", res));
                return new ApiResponse(200, "门店管理员登陆成功", res);
            } else {
                return new ApiResponse(410, "账号或密码错误", null);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Transactional
    @Override
    public ApiResponse getStoreReservation(String token) {
        try {
            String storeAdminId = JwtUtil.getId(token);
            String storeId = storeMapper.getStoreId(storeAdminId);
            List<Reservation> reservations = reservationMapper.getAllPossibleReservation(storeId);
            if (reservations != null && !reservations.isEmpty()) {
                return new ApiResponse(200, "门店订单查找成功", reservations);
            } else {
                return new ApiResponse(411, "没有找到相关门店订单", null);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Transactional
    @Override
    public ApiResponse getStoreCarCount(String token) {
        try {
            String storeAdminId = JwtUtil.getId(token);
            String storeId = storeMapper.getStoreId(storeAdminId);
            List<CarCount> carCounts = carMapper.selectCountByStoreID2(storeId);
            if (carCounts != null && !carCounts.isEmpty()) {
                return new ApiResponse(200, "门店车辆数量查找成功", carCounts);
            } else {
                return new ApiResponse(412, "没有找到车辆数量信息", null);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Transactional
    @Override
    public ApiResponse getStoreCar(String token) {
        try {
            String storeAdminId = JwtUtil.getId(token);
            String storeId = storeMapper.getStoreId(storeAdminId);
            List<Car> cars = carMapper.selectCarsWithModelsByStoreID(storeId);
            if (cars != null && !cars.isEmpty()) {
                return new ApiResponse(200, "门店车辆查找成功", cars);
            } else {
                return new ApiResponse(413, "没有找到车辆信息", null);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Transactional
    @Override
    public ApiResponse confirmStoreReservation(String token, String reservationID, String userID) {
        try {
            java.util.Date now = new java.util.Date();
            String storeAdminId = JwtUtil.getId(token);
            String storeId = storeMapper.getStoreId(storeAdminId);
            Reservation reservation = reservationMapper.selectById(reservationID);
            if (reservation == null) {
                return new ApiResponse(414, "预订信息查询失败", null);
            }
            if (!reservation.getReservationStatus().equals("未借出")) {
                return new ApiResponse(417, "订单状态异常", null);
            }
            if (!reservation.getUserID().equals(userID)) {
                return new ApiResponse(427, "用户核实失败", null);
            }
            if (!reservation.getExpectedCheckoutStoreID().equals(storeId)) {
                return new ApiResponse(428, "门店核实失败", null);
            }
            if (!reservation.getExpectedCheckoutTime().toLocalDate().equals(now.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate())) {
                return new ApiResponse(428, "时间核实失败", null);
            }

            CarCount carCount = carMapper.selectByStoreIDCarModelID(storeId, reservation.getCarModelID());
            if (carCount.getCount() < 1) {
                return new ApiResponse(415, "剩余车辆不足，请调度车辆", null);
            }
            Car car = carMapper.selectRandomAvailableCarByStoreIDAndCarModelID(storeId, reservation.getCarModelID());
            if (car == null) {
                return new ApiResponse(416, "无法分配车辆", null);
            }
            carMapper.updateCarStatusAndCondition(car.getCarID(), "已租", "良好");
            reservationMapper.updateReservation(reservationID, "借出", reservation.getRenewalPermission());
            actualOrderMapper.insert(new ActualOrder(reservation.getReservationID(), new Date(now.getTime()), storeId, null, null, car.getCarID(), reservation.getUserID(), 0));
            return new ApiResponse(200, "成功分配车辆", car);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Transactional
    @Override
    public ApiResponse requestCarTransfer(String token, String carModelID) {
        try {
            LocalDate now = getCurrentDate();
            String storeAdminId = JwtUtil.getId(token);
            String storeId = storeMapper.getStoreId(storeAdminId);
            List<CarStoreCount> carStoreCounts = carMapper.selectCarCountByCarModelOrderByCountDesc(carModelID,storeId);
            if (carStoreCounts == null) {
                return new ApiResponse(440, "车辆不足，无法调取", null);
            }
            for (CarStoreCount carStoreCount : carStoreCounts) {
                if (carStoreCount.getCount() > 0&&!carStoreCount.getStoreID().equals(storeId)) {
                    CarCount carCount = new CarCount(carStoreCount.getCarModelID(), carStoreCount.getCount());
                    List<Reservation> reservations = reservationMapper.getAllPossibleReservation(carStoreCount.getStoreID());
                    for (Reservation reservation : reservations) {
                        if (reservation.getExpectedCheckoutTime().toLocalDate().equals(now)) {
                            carCount.setCount(carCount.getCount() - 1);
                        }
                    }
                    if (carCount.getCount() > 0) {
                        Car car = carMapper.selectRandomAvailableCarByStoreIDAndCarModelID(carStoreCount.getStoreID(), carCount.getCarModelID());
                        carMapper.updateCarBelonging(car.getCarID(), storeId);
                        return new ApiResponse(200, "成功调取车辆，从" + carStoreCount.getStoreID(), car);
                    }
                }
            }
            return new ApiResponse(440, "车辆不足，无法调取", null);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Transactional
    @Override
    public ApiResponse returnCar(String token, String reservationID) {
        try {
            java.util.Date now = new java.util.Date();
            String storeAdminId = JwtUtil.getId(token);
            String storeId = storeMapper.getStoreId(storeAdminId);
            if (storeId == null) {
                return new ApiResponse(403, "管理员权限验证失败", null);
            }

            Reservation reservation = reservationMapper.selectById(reservationID);
            if (reservation == null) {
                return new ApiResponse(414, "预订信息查询失败", null);
            }

            if (!(reservation.getReservationStatus().equals("借出") || reservation.getReservationStatus().equals("逾期"))) {
                return new ApiResponse(417, "订单状态异常，无法还车", null);
            }
            ActualOrder actualOrder = actualOrderMapper.selectById(reservation.getReservationID());
            Car car = carMapper.selectById(actualOrder.getCarID());
            if (car == null) {
                return new ApiResponse(416, "车辆信息不存在", null);
            }
            carMapper.updateCarStatusAndCondition(car.getCarID(), "可租", "良好");
            carMapper.updateCarBelonging(car.getCarID(), storeId);
            reservationMapper.updateReservation(reservationID, "已还", "否");
            CarModel carModel = carModelMapper.selectById(car.getCarModelID());
            long daysBetween = Duration.between(actualOrder.getCheckoutTime().toLocalDate().atStartOfDay(), now.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate().atStartOfDay()).toDays();
            float price = carModel.getPrice() * daysBetween;
            if(reservation.getReservationStatus().equals("逾期")){
                price+=1000;
            }
            actualOrder.setAmount(price);
            actualOrder.setReturnTime(new Date(now.getTime()));
            actualOrder.setReturnStoreID(storeId);
            actualOrderMapper.updateById(actualOrder);
            return new ApiResponse(200, "还车成功，车辆状态更新为可租", actualOrder);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
